<?php
namespace app\admin\controller;

use think\Controller;

/**
 * 通用Controller类
 */
class Common extends Controller {

    public function _initialize() {
        if (!session('?admin_auth')) {
            session('go', 'admin/index/index');
            $this->redirect('admin/auth/login');
        }
        \think\Hook::add('app_end', 'app\\admin\\behavior\\Clearcache');
        \think\Hook::listen('admin_init');
        \think\Config::set('app_trace', false);
    }

    /**
     * 获取数据
     *
     * @param array $p
     * @return void
     */
    protected function modeldata($p = []) {
        $request = request();
        if (!$p) {
            $p = $request->param();
        }
        if (!isset($p['model'])) {
            $p['model'] = $request->controller();
        }
        if (!isset($p['where'])) {
            $p['where'] = [];
        } else {
            foreach ($p['where'] as &$a) {
                foreach ($a as &$b) {
                    $b = is_string($b) ? trim($b) : $b;
                }
            }
        }
        if (!isset($p['with'])) {
            $p['with'] = '';
        }
        $m = \think\Loader::model($p['model']);
        // 获取排序
        if (input('order/a')) {
            $m->order(input('order/a'));
        }
        $result = [];
        // 获取内容
        $rows = input('rows', 0, 'intval') ?: 1000;
        $result = $m::with($p['with'])->where($p['where'])->paginate($rows);
        $result = $result->toArray();
        $result['rows'] = $result['data'];
        unset($result['data']);

        $this->success('获取成功！', '', $result);
    }

    protected function fetchform($data = array(), $config = array()) {
        $form = $this->getform($data, $config);
        $this->assign($form);
        $this->assign('_data', $data);
        $this->success('', '', $this->fetch('admin@common/form'));
    }

    /** 
     * 返回表单
     */
    protected function getform($data = array(), $config = array()) {

        $res = [];

        $config['formname'] = isset($config['formname']) ? $config['formname'] : request()->module() . '_' . request()->controller() . '_' . request()->action();
        $config['action'] = isset($config['action']) ? $config['action'] : request()->module() . '/' . request()->controller() . '/' . request()->action();
        $_where = [
            'status' => array('eq', 1),
            'name' => array('eq', $config['formname']),
        ];
        if ($form = \think\Db::name('form')->where($_where)->find()) {
            $_where = [
                'status' => array('eq', 1),
                'category_id' => array('eq', $form['id']),
            ];
            $_fields = \app\admin\model\Formfield::where($_where)->field(true)->order('sort desc,id asc')->select();
            $groups = [];
            foreach ($_fields as $key => $value) {
                $tmp = [];
                // 字段配置
                $tmp['id'] = $value['id'];
                $tmp['config'] = $value['config'];
                $tmp['title'] = $value['title'];
                $tmp['remark'] = $value['remark'];
                $tmp['type'] = substr($value['type'], 5);
                // 字段名称
                if ($value['subtable'] && $value['extfield']) {
                    $tmp['field'] = $value['subtable'] . '[' . $value['extfield'] . ']' . '[' . $value['name'] . ']';
                } elseif ($value['extfield']) {
                    $tmp['field'] = $value['extfield'] . '[' . $value['name'] . ']';
                } elseif ($value['subtable']) {
                    $tmp['field'] = $value['subtable'] . '[' . $value['name'] . ']';
                } else {
                    $tmp['field'] = $value['name'];
                }
                // 字段值
                switch ($value['defaultvaluetype']) {
                    case '0':
                        $tmp['value'] = $value['defaultvalue'];
                        break;

                    case '1':
                        $tmp['value'] = input($value['defaultvalue']);
                        break;

                    case '2':
                        $tmp['value'] = config($value['defaultvalue']);
                        break;

                    case '3':
                        if ($value['subtable'] && $value['extfield']) {
                            $_value = $data[$value['subtable']][$value['extfield']];
                        } elseif ($value['extfield']) {
                            $_value = $data[$value['extfield']];
                        } elseif ($value['subtable']) {
                            $_value = $data[$value['subtable']];
                        } else {
                            $_value = $data;
                        }
                        $tmp['value'] = $this->get_point_value($_value, $value['defaultvalue']);
                        break;

                    default:
                        $tmp['value'] = $value['defaultvalue'];
                        break;
                }
                $groups[$value['group']][$value['id']] = $tmp;
            }
            $form['action'] = \think\Url::build($config['action']);
            $form['formtime'] = time();
            $res['_form'] = $form;
            $res['_groups'] = $groups;

            // 扩展字段
            if (isset($config['ext_id']) && $config['ext_id']) {
                $_where = array(
                    'category_id' => array('eq', $config['ext_id']),
                    'status' => array('eq', 1),
                );
                if ($extfields = \app\admin\model\Extendfield::where($_where)->field(true)->order('sort desc,id asc')->select()) {
                    $extgroups = [];
                    foreach ($extfields as $key => $extfield) {
                        $tmp = [];
                        // 字段配置
                        $tmp['id'] = $extfield['id'];
                        $tmp['config'] = $extfield['config'];
                        $tmp['title'] = $extfield['title'];
                        $tmp['remark'] = $extfield['remark'];
                        $tmp['type'] = substr($extfield['type'], 5);
                        // 字段名称
                        if (isset($config['ext_table']) && $config['ext_table']) {
                            $tmp['field'] = $config['ext_table'] . '[ext]' . '[' . $extfield['name'] . ']';
                        } else {
                            $tmp['field'] = 'ext[' . $extfield['name'] . ']';
                        }
                        // 字段值
                        $tmp['value'] = '';
                        if ($data) {
                            if (isset($config['ext_table']) && $config['ext_table']) {
                                $_value = $data[$config['ext_table']]['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']]) ? $_value[$extfield['name']] : $extfield['value'];
                            } elseif (isset($data['ext'])) {
                                $_value = $data['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']]) ? $_value[$extfield['name']] : $extfield['value'];
                            }
                        }
                        $extgroups[$extfield['group']][$extfield['id']] = $tmp;
                    }
                    $res['_extgroups'] = $extgroups;
                }
            } elseif (isset($config['single_ext_id']) && $config['single_ext_id']) {
                $_where = array(
                    'single_id' => array('eq', $config['single_ext_id']),
                    'status' => array('eq', 1),
                );
                if ($extfields = \app\admin\model\Extendfield::where($_where)->field(true)->order('sort desc,id asc')->select()) {
                    $extgroups = [];
                    foreach ($extfields as $key => $extfield) {
                        $tmp = [];
                        // 字段配置
                        $tmp['id'] = $extfield['id'];
                        $tmp['config'] = $extfield['config'];
                        $tmp['title'] = $extfield['title'];
                        $tmp['remark'] = $extfield['remark'];
                        $tmp['type'] = substr($extfield['type'], 5);
                        // 字段名称
                        if (isset($config['ext_table']) && $config['ext_table']) {
                            $tmp['field'] = $config['ext_table'] . '[ext]' . '[' . $extfield['name'] . ']';
                        } else {
                            $tmp['field'] = 'ext[' . $extfield['name'] . ']';
                        }
                        // 字段值
                        $tmp['value'] = '';
                        if ($data) {
                            if (isset($config['ext_table']) && $config['ext_table']) {
                                $_value = $data[$config['ext_table']]['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']]) ? $_value[$extfield['name']] : $extfield['value'];
                            } elseif (isset($data['ext'])) {
                                $_value = $data['ext'];
                                $tmp['value'] = isset($_value[$extfield['name']]) ? $_value[$extfield['name']] : $extfield['value'];
                            }
                        }
                        $extgroups[$extfield['group']][$extfield['id']] = $tmp;
                    }
                    $res['_extgroups'] = $extgroups;
                }
            }

            if (input('__modal') == 1) {
                $res['__modal'] = 1;
            } else {
                $res['__modal'] = 0;
            }
            $res['namespace'] = ns();
            return $res;
        } else {
            $this->error('表单配置错误！');
        }
    }

    protected function ebadd($config = [], $back = false) {
        if (request()->isGet()) {
            $this->fetchform();
        } else if (request()->isPost()) {
            $config['model'] = isset($config['model']) ? $config['model'] : get_model_controller(request()->controller());
            $config['module'] = isset($config['module']) ? $config['module'] : request()->module();
            $m = \think\Loader::model($config['module'] . '/' . $config['model']);
            $input = input();
            $config['allowfield'] = isset($config['allowfield']) ? $config['allowfield'] : true;
            $config['validate'] = isset($config['validate_scene']) ? $config['model'] . '.' . $config['validate_scene'] : $config['model'];
            if (false !== $id = $m->allowField($config['allowfield'])->validate($config['validate'])->save($input)) {
                if (isset($config['relation']) && $config['relation']) {
                    foreach ($config['relation'] as $relation => $opt) {
                        switch ($opt['type']) {
                            case 'hasone':
                                $m->$relation()->save($input[$relation]);
                                break;
                            case 'hasmany':
                                $m->$relation()->saveAll($input[$relation]);
                                break;
                            case 'manytomany':
                                $m->$relation()->saveAll($input[$relation]);
                                break;
                        }
                    }
                }
                if ($back == true) {
                    return $id;
                } else {
                    $this->success('新增成功！', '', ['id' => $id]);
                }
            } else {
                $this->error($m->getError());
            }
        }
    }

    protected function ebedit($config = [], $back = false) {
        if (request()->isGet()) {
            $id = isset($config['id']) ? $config['id'] : input('id');
            $config['model'] = isset($config['model']) ? $config['model'] : get_model_controller(request()->controller());
            $config['module'] = isset($config['module']) ? $config['module'] : request()->module();
            $m = \think\Loader::model($config['module'] . '/' . $config['model']);
            $this->fetchform($m->get($id));
        } else if (request()->isPost()) {
            $id = isset($config['id']) ? $config['id'] : input('id');
            $config['model'] = isset($config['model']) ? $config['model'] : get_model_controller(request()->controller());
            $config['module'] = isset($config['module']) ? $config['module'] : request()->module();
            $m = \think\Loader::model($config['module'] . '/' . $config['model']);
            $data = $m->get($id);
            $input = input();
            $config['allowfield'] = isset($config['allowfield']) ? $config['allowfield'] : true;
            $config['validate'] = isset($config['validate_scene']) ? $config['model'] . '.' . $config['validate_scene'] : $config['model'];
            if (false !== $m->allowField($config['allowfield'])->validate($config['validate'])->save($input, ['id' => $id])) {
                if (isset($config['relation']) && $config['relation']) {
                    foreach ($config['relation'] as $relation => $opt) {
                        switch ($opt['type']) {
                            case 'hasone':
                                $opt['validate'] = isset($opt['validate_scene']) ? $relation . '.' . $opt['validate_scene'] : $relation;
                                $opt['allowfield'] = isset($opt['allowfield']) ? $opt['allowfield'] : true;
                                if (false === $m->$relation->allowField($opt['allowfield'])->validate($opt['validate'])->save($input[$relation])) {
                                    $this->error($m->$relation->getError());
                                }
                                break;
                            case 'hasmany':
                                $m->$relation()->delete();
                                $m->$relation()->saveAll($input[$relation]);
                                break;
                            case 'manytomany':
                                $m->$relation()->detach(true);
                                $m->$relation()->saveAll($input[$relation]);
                                break;
                        }
                    }
                }
                if ($back == true) {
                    return true;
                } else {
                    return $this->success('修改成功！');
                }
            } else {
                $this->error($m->getError());
            }
        }
    }

    protected function ebdelete($config = [], $data = []) {
        if (false !== $res = $this->_ebdelete($config, $data)) {
            $this->success('删除成功！', '', $res);
        } else {
            $this->error('删除失败！');
        }
    }

    // 删除
    protected function _ebdelete($config = [], $data = []) {

        if (isset($data['ids'])) {
            $ids = (array)$data['ids'];
        } elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }

        if ($ids) {
            $config['model'] = isset($config['model']) ? $config['model'] : get_model_controller(request()->controller());
            $config['module'] = isset($config['module']) ? $config['module'] : request()->module();
            $m = \think\Loader::model($config['module'] . '/' . $config['model']);
            $map['id'] = array('in', $ids);
            if (isset($config['relation']) && $config['relation']) {
                $lists = $m->where($map)->select();
                if ($lists) {
                    foreach ($lists as $vo) {
                        foreach ($config['relation'] as $relation => $opt) {
                            switch ($opt['type']) {
                                case 'hasone':
                                    if (isset($opt['sub'])) {
                                        $this->_ebdelete($opt['sub'], ['ids' => $vo['id']]);
                                    }
                                    $vo->$relation->delete();
                                    break;
                                case 'hasmany':
                                    if (isset($opt['sub'])) {
                                        $rel = $vo->$relation;
                                        $subids = [];
                                        foreach ($rel as $re) {
                                            $subids[] = $re['id'];
                                        }
                                        if ($subids) {
                                            $this->_ebdelete($opt['sub'], ['ids' => $subids]);
                                        }
                                    }
                                    $vo->$relation()->delete();
                                    break;
                                case 'manytomany':
                                    $vo->$relation()->detach(true);
                                    break;
                            }
                        }
                        $vo->delete();
                    }
                }
            } else {
                $lists = $m->where($map)->select();
                $m->where($map)->delete();
            }
            $res = [];
            foreach ($lists as $list) {
                $res[] = $list->toArray();
            }
            return $res;
        } else {
            return false;
        }
    }

    // 审核
    protected function ebstatus($config = []) {

        if (isset($config['ids'])) {
            $ids = (array)$config['ids'];
        } elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }
        if (empty($ids)) {
            $this->error('请选择要 操作 的数据！');
        }

        if (isset($config['value'])) {
            $value = (int)$config['value'];
        } else {
            $value = input('value', 0, 'intval') ? 1 : 0;
        }

        $this->ebfield($ids, 'status', $value, $config);

    }

    // 排序 推荐
    protected function ebsort($config = []) {

        if (isset($config['ids'])) {
            $ids = (array)$config['ids'];
        } elseif ($ids = input('ids')) {
            $ids = explode(',', $ids);
        }
        if (empty($ids)) {
            $this->error('请选择要 操作 的数据！');
        }

        if (isset($config['value'])) {
            $value = (int)$config['value'];
        } else {
            $value = input('value', 0, 'intval');
        }

        $this->ebfield($ids, 'sort', $value, $config);

    }

    protected function ebfield($ids, $field, $value, $config = []) {

        $config['model'] = isset($config['model']) ? $config['model'] : get_model_controller(request()->controller());
        $config['module'] = isset($config['module']) ? $config['module'] : request()->module();
        $m = \think\Loader::model($config['module'] . '/' . $config['model']);

        $where = [];
        $where['id'] = array('in', $ids);
        $num = $m->where($where)->setField($field, $value);
        if (false === $num) {
            $this->error('操作失败！');
        } elseif (is_numeric($num)) {
            $this->success('操作成功！');
        }
    }

    private function get_point_value($data = [], $str) {
        $pos = strpos($str, '.');
        if (false === $pos) {
            return isset($data[$str]) ? $data[$str] : false;
        } else {
            $key = mb_substr($str, 0, $pos);
            if (isset($data[$key])) {
                return $this->get_point_value($data[$key], mb_substr($str, $pos + 1));
            } else {
                return false;
            }
        }
    }

    // 空控制器
    public function _empty() {
        $action = request()->action();
        switch ($action) {
            case 'add':
                if (request()->isGet()) {
                    $this->fetchform();
                } elseif (request()->isPost()) {
                    $this->ebadd();
                }
                break;

            case 'edit':
                if (request()->isGet()) {
                    $data = \think\Db::name(request()->controller())->find(input('id'));
                    $this->fetchform($data);
                } elseif (request()->isPost()) {
                    $this->ebedit();
                }
                break;

            // 排序
            case 'resort':
                if (request()->isGet()) {
                    // $this -> fetchform();
                } elseif (request()->isPost()) {
                    $this->ebsort();
                }
                break;

            // 删除
            case 'delete':
                $this->ebdelete();
                break;

            // 审核
            case 'status':
                $this->ebstatus();
                break;

            default:
                $this->error('错误请求！');
                break;
        }
    }

}